מפתחות ואינדקסים אלו הדברים שעושים את השליפות מהירות ועוזרים למסדי הנתונים לארגן נכון את הנתונים בזכרון. מה זה ואיך זה עובד - בהמשך המאמר.
מפתחות במסד
המילה "מפתח" (וגם "אינדקס") כבר מוכרת לנו מנושא המערכים. במערך, המפתח הוא המזהה של הערך.
$a = array("key" => "value", "key2" => "value2");
המפתח הוא מזהה ייחודי של אלמנט במערך. לפעמים, כשהוא מספר, המפתח נקרא גם אינדקס, אבל בשני המקרים הכוונה לאותו דבר - מזהה ייחודי של אלמנט במערך.
Primary key - מפתח ראשי
המפתח הראשי הוא המזהה הייחודי של שורה בטבלה. ברוב המקרים זהו שדה בשם ID; לכל שורה יש id משלה שמסוגל להצביע על שורה אחת בטבלה במדויק. לא יכולות להיות שתי שורות עם אותו ערך של מפתח ראשי (כלומר, עם אותו id) כמו שלא יכולים להיות במערך שני אלמנטים עם אותו מפתח.
כמובן שאין חובה לקרוא לשדה הראשי id או שיהיה בכלל מספרי, אבל כן חובה שהערכים של שדה ה-Primary key יהיו שונים משורה לשורה כדי לזהות את השורה באופן ייחודי.
Unique - ייחודי
Unique זוהי הגבלה על הנתונים בעמודה מסוימת האומרת שבכל שורה בטבלה, הערך של הטור הזה חייב להיות שונה, ייחודי.
כלומר, לא יכולות להיות שתי שורות בטבלה שיהיה להן ערך זהה בעמודה "username". כמובן שנוכל לבדוק בקוד עצמו האם שם המשתמש תפוס, אבל זוהי אפשרות מובנית שנותן מסד הנתונים - להגביל בכוחות עצמו את הנתונים בשדה מסויים, כך שבכל שורה ערך של שדה יהיה ייחודי - Unique.
למרות שנוכל לבדוק בקוד האם שם המשתמש תפוס לפני ההרשמה, חשבו מה קורה אם שני משתמשים מנסים להירשם ממש במקביל עם אותו שם משתמש. הסקריפט הראשון מבצע בדיקה, מגלה שהשם פנוי ובזמן שהוא מחשב כל מיני hashים של סיסמאות - בדיוק מגיע הסקריפט השני וגם הוא רואה שהשם פנוי (כי הסקריפט הראשון עוד לא הכניס משהו למסד).
הסקריפט הראשון סיים את החישובים והחליט לרשום את המשתמש למסד. אחרי שהסקריפט השני יסיים את החישובים - גם הוא ינסה לרשום את המשתמש למסד (כי את הבדיקה הוא כבר עשה). במקרה הזה יירשמו שני משתמשים עם אותו שם והגבלה בכוחות המסד עצמו יכולה דווקא להועיל פה.
Index - מפתח עניינים
את אופציה זו נותנים לשדה (טור) ממנו עושים שליפות מרובות, כיוון שהמסד מסתמך עליו כדי למצוא את הנתונים. מסד הנתונים, אחרי הכל, גם הוא שומר את הנתונים בקבצים על הדיסק הקשיח. בתור תוכנה חכמה - המסד מנהל אותם בדרך משלו, מפרק נתונים לקבצים שונים, רושם אותם באופן מסוים שרק הוא מבין וכל זה כדי לייעל את השליפות ולספק תוצאות בזמן קצר.
אילו יהיה לכם קובץ של משתמשים בשם "users.txt", ובכל שורה בו היו מופיעים שם וסיסמא של משתמש - כדי לבדוק סיסמא של משתמש כלשהו, הייתם צריכים לטעון את כל הקובץ, לעבור שורה אחרי שורה, לקרוא את התוכן שלו ולהחליט האם זו השורה שאתם צריכים כדי להשוות סיסמאות.
Index על שדה מאפשר למסד לייעל את השמירה; באופן נפרד הוא גם ישמור לעצמו רשומה (משתמש אלכס נמצא בשורה 57), ואז לא יצטרך לקרוא קובץ ענק של אלפי משתמשים עם המון נתונים בכל שורה, אלא יוכל ישר לגשת לשורה 57 ולקרוא רק את תוכן השורה הנכונה. כלומר, המסד יוצר לעצמו אינדקס, מעין תוכן עניינים, כדי שיוכל לגשת ישירות למידע הנחוץ במקום לסרוק את כל הנתונים.
נניח שיש לכם הרבה שליפות מסוג where username=Alex. בלי אינדקס על השדה username, המסד יצטרך לעבור על כל הנתונים ולחפש באיזה מהם כתוב Alex. אם יש לו אינדקס, הוא יוכל לגשת ישירות למיקום שבו מתחילים השמות באות A ולסרוק רק אותם, מכיוון שהם מסודרים אצלו ברשימה נפרדת לפי הסדר. באופן הזה כמות השורות שעל המסד לעבור כדי להחזיר תשובה הרבה יותר קטנה מכמות השורות שעליו לעבור בסריקה מלאה של הטבלה, ולכן השליפות מהירות הרבה יותר.
שדה Index אינו אומר שהערכים חייבים להיות ייחודיים. יכולים להיות כמה Alex בטבלה שלכם, ובכל זאת, כדי לייעל את השליפה ולא לסרוק את כל הטבלה - תגדירו את השדה כאינדקס.
לסיכומו של דבר
Primary key = Unique + Index
שדות שיש לפיהן הרבה שליפות יש להגדיר כ-Index.
שדות שהערכים שלהן צריכים להיות ייחודיים בכל שורה יש להגדיר כ-Unique.
לעשות את כל זה אפשר באמצעות כפתורים ב-phpMyAdmin:
תגובות לכתבה:
מעולה :)
תודה :)
יפה מאוד, מדריך מעולה :)
תודה ממש עזר לי D:
המשך כך.
הרגע הבנתי שלא רשמתי דבר חשוב.
את כל שוגי המפתחות אפשר לשים במקביל על כמה שדות. אם יש לכם שליפה קבוע לפי שני שדות (שם + שם משפחה) עדיף לסמן בווי את שני השדות וללחוץ על כפתור הindex. אינדקס אחד יווצר על שני השדות ביחד ולא שני אידקסים נפרדים לכל שדה.
כנ"ל לגבי unique שיכול להגביל ערכים של שני שדות ביחד. למשל יכולים להיות לכם הרבה רשומות של name=Alex
אבל רק רשומה אחת של name=Alex and surname=Raskin
כלומר ההגבלה תחול רק במקרים שבהם הערכים של שני השדות ביחד כבר קיימים בטבלה.
מדריך מעולה, מאוד עזר לי. תודה רבה. :)
קודם כל מדריך מעולה!
ויש לי גם שאלה אם אני הגדרתי את ID כPRIMARY KEY ואני משתמש בו הרבה לשליפות אז אני צריך להגדיר אותו גם כINDEX
אשמח אם גם תסביר במה עוזר PRIMARY KEY בשליפות מהמסד.
לא צריך להגדיר את ID *גם* בתור אינדקס כי כמו שכתוב למעלה
primary key = index + unique
ככה שהשדה הזה אוטומטית הופל להיות אינדקס. ולא סתם אינדקס, אלה האינדקס הראשי של הטבלה, כלומר הכי מהיר ויעיל.
כתוב כאן http://www.internet-israel.com/internet/מדריכים/mysql-מדריכים/מפתחות-ראשיים-ב-mysql/ ש-Unique זה אוטומטית אינדקס. ופה כתוב שאינדקס שהוא Unique הוא בעצם מפתח ראשי. לא הבנתי איך זה מסתדר.
unique אינו אינדקס, אלה הגבלה על ערכים ייחודיים בשורה.
אבל אם יש עמודה שהיא גם אינדקס וגם יוניק = היא שוות ערך בפונקציונליות שלה למפתח ראשי.
המממ... יכול להיות שהוא התכוון לכתוב אחרת.
"מפתח ייחודי שאינו מפתח ראשי הוא פשוט אינדקס שנוצר כייחודי. אם אנו מגדירים שדה מסוים כאינדקס ייחודי, אז זה בדיוק כמו להגדיר אותו כמפתח ייחודי."
במקום "זה בדיוק כמו להגדיר אותו כמפתח ייחודי" - "זה בדיוק כמו להגדיר אותו כמפתח ראשי"...
אני לא יודע מה הוא ניסה להגיד ואני לא ממש רוצה לנחש מה הוא רצה לכתוב במקום מה שהוא כתב,
אבל הגדרה של שדה בתור יוניק (ייחודי) אינו גורמת לו להיות אינדקס.
חשוב גם להוסיף מידע על foreign key.
קשרים בין טבלאות זה סיפור למדריך נפרד :)
בעקבות השאלה שנשאלה כאן -
[url="http://phpguide.co.il/q2027/איך יותר כדאי לבדוק התחברות .htm"]מה ההבדל בין unique ל primary key[/url] אני מציע להוסיף את ההבדלים